/**
 * Wihidum - Efficient Broker Hierarchy for Publish Subscribe Middleware
 *
 * License      :   Apache License 2.0
 * Home Page    :   http://code.google.com/p/wihidum/
 * Mailing List :   wihidum@googlegroups.com
 */

package lk.mrt.cse.wihidum.subscriber.receiver;

import lk.mrt.cse.wihidum.subscriber.processor.*;
import lk.mrt.cse.wihidum.util.*;
import lk.mrt.cse.wihidum.client.BrokerRetrievalClient;
import org.apache.axiom.om.*;
import org.apache.axiom.soap.*;
import org.apache.axis2.*;
import org.apache.axis2.context.*;
import org.apache.axis2.receivers.*;
import org.apache.log4j.*;

/**
 * Entry point of the messages received to the service
 */
public class MessageReceiver
        extends AbstractInOutMessageReceiver
{

    private static final Logger logger = Logger.getLogger (MessageReceiver.class);
    private Processor subscriptionProcessor;
    private Processor getPublicationsProcessor;

    /**
     * Default contructor
     */
    public MessageReceiver ()
    {
        getPublicationsProcessor = new GetPublicationsProcessor ();
        subscriptionProcessor = new SubscriptionProcessor ();
    }

    /**
     * Process the messages
     *
     * @param inMessage  Incoming message context
     * @param outMessage Outgoing message context
     * @throws AxisFault Exception
     */
    public void invokeBusinessLogic (MessageContext inMessage, MessageContext outMessage)
            throws AxisFault
    {
        //logger.info ("Subscriber service received a new message");

        try
        {
            // Get hold of the request SOAP Envelope
            SOAPEnvelope requestEnvelop = inMessage.getEnvelope ();

            // Get the body element of request SOAP envelop
            SOAPBody requestEnvelopBody = requestEnvelop.getBody ();

            //Get the actual request content element from SOAPBody
            OMElement messageElement = requestEnvelopBody.getFirstElement ();

            //Get the header element of the content element
            OMElement requestHeaderElement = messageElement.getFirstElement ();

            //Get the Action element which is the first element inside the header in all cases
            OMElement actionElement = requestHeaderElement.getFirstElement ();

            //Get the action in order to delegate the processing of the request accordingly
            String action = actionElement.getText ();

            // The response element
            OMElement responseElement;

            if (action.equals (WihidumConstants.Operations.SUBSCRIBE))
            {
                logger.info ("Received message to subscriber service is a subscription request");

                // Hand over the message to the subscription processor
                responseElement = subscriptionProcessor.processMessage (messageElement);

                // Set the response envelope in the response message context
                outMessage.setEnvelope (createResponse (responseElement));
            }
            else if (action.equals (WihidumConstants.Operations.GET_PUBLICATIONS))
            {
                logger.info ("Received message is a get publications request");

                // Hand over the message to the publication processor
                responseElement = getPublicationsProcessor.processMessage (messageElement);

                // Set the response envelope in the response message context
                outMessage.setEnvelope (createResponse (responseElement));
            }
            else
            {
                logger.info ("Received message is in unrecognized format");
            }
        }
        catch (NullPointerException ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
        catch (OMException ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
        catch (AxisFault ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
    }

    /**
     * Create response SOAP envelop
     *
     * @param element Response element
     * @return Created response envelop
     */
    private SOAPEnvelope createResponse (OMElement element)
    {
        // Create the response SOAP facotry
        SOAPFactory factory = OMAbstractFactory.getSOAP11Factory ();

        // Create the response SOAP envelop
        SOAPEnvelope responseEnvelop = factory.getDefaultEnvelope ();

        // Add the response to the response SOAP envelop
        responseEnvelop.getBody ().addChild (element);

        return responseEnvelop;
    }

    /**
     * Get publications processor setter method
     *
     * @param getPublicationsProcessor PublicationProcessor
     */
    public void setGetPublicationsProcessor (Processor getPublicationsProcessor)
    {
        this.getPublicationsProcessor = getPublicationsProcessor;
    }

    /**
     * Subscription processor setter method
     *
     * @param subscriptionProcessor SubscriptionProcessor
     */
    public void setSubscriptionProcessor (Processor subscriptionProcessor)
    {
        this.subscriptionProcessor = subscriptionProcessor;
    }

}
